import { Role, IRole } from '../models/role'
import {
  DatabaseError,
  NotFoundError,
  ValidationError
} from '../errors/CustomError'
import { isMongoError } from '../errors/MongoError'

class RoleService {
  // 创建角色
  async create(roleData: Partial<IRole>): Promise<IRole> {
    try {
      const role = new Role(roleData)
      return await role.save()
    } catch (error) {
      if (isMongoError(error) && error.code === 11000) {
        const mongoError = error as any
        if (mongoError.keyValue?.name) {
          throw new ValidationError('角色名称已存在')
        }
        if (mongoError.keyValue?.code) {
          throw new ValidationError('角色编码已存在')
        }
        throw new ValidationError('角色数据重复')
      }

      if (error instanceof Error && error.name === 'ValidationError') {
        throw new ValidationError('角色数据验证失败', (error as any).errors)
      }

      throw new DatabaseError('创建角色失败', error)
    }
  }

  // 删除角色
  async delete(id: number): Promise<boolean> {
    try {
      const result = await Role.findOneAndDelete({ id })

      if (!result) {
        throw new NotFoundError('角色未找到')
      }

      return true
    } catch (error) {
      if (error instanceof NotFoundError) {
        throw error
      }
      throw new DatabaseError('删除角色失败')
    }
  }

  // 更新角色
  async update(id: number, updateData: Partial<IRole>): Promise<IRole | null> {
    try {
      // 移除不能更新的字段
      const { id: roleId, created_at, ...updateFields } = updateData

      const role = await Role.findOneAndUpdate({ id }, updateFields, {
        new: true
      })

      if (!role) {
        throw new NotFoundError('角色未找到')
      }

      return role
    } catch (error) {
      if (error instanceof NotFoundError || error instanceof ValidationError) {
        throw error
      }
      if (isMongoError(error) && error.code === 11000) {
        const mongoError = error as any
        if (mongoError.keyValue?.name) {
          throw new ValidationError('角色名称已存在')
        }
        if (mongoError.keyValue?.code) {
          throw new ValidationError('角色编码已存在')
        }
        throw new ValidationError('角色数据重复')
      }

      if (error instanceof Error && error.name === 'ValidationError') {
        throw new ValidationError('角色数据验证失败', (error as any).errors)
      }
      throw new DatabaseError('更新角色失败')
    }
  }

  // 查询角色
  async findAll(query: any): Promise<{ list: IRole[]; total: number }> {
    try {
      const page = Math.max(Number(query.page) || 1, 1)
      const size = Math.max(Number(query.size) || 10, 1)
      const type = query.type?.toString() || ''

      const skip = (page - 1) * size
      const filter: any = {}

      // 模糊匹配条件
      if (query.name) {
        filter.name = { $regex: query.name, $options: 'i' }
      }

      // 根据查询条件计算总数
      const total = await Role.countDocuments(filter)

      if (type === 'all') {
        const list = await Role.find(filter)
        return {
          list,
          total
        }
      }

      const list = await Role.find(filter).skip(skip).limit(size)
      return {
        list,
        total
      }
    } catch (error) {
      throw new DatabaseError('查询角色列表失败')
    }
  }

  // 查询单个角色
  async findOne(id: number): Promise<IRole | null> {
    try {
      const role = await Role.findOne({ id })

      if (!role) {
        throw new NotFoundError('角色未找到')
      }

      return role
    } catch (error) {
      if (error instanceof NotFoundError) {
        throw error
      }
      throw new DatabaseError('查询角色失败')
    }
  }
}

export default new RoleService()
